package com.jeecg.modules.controller;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Streams;
import com.google.common.io.CharStreams;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;
import com.jayway.jsonpath.TypeRef;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jeecg.modules.entity.JimuReportDb;
import com.jeecg.modules.response.Result;
import com.jeecg.modules.response.ResultGenerator;
import com.jeecg.modules.service.JimuReportDbService;
import com.jeecg.modules.vo.ApiFormVO;
import com.jeecg.modules.vo.ApiSelectVO;
import com.yiidata.dataops.common.utils.RestApiUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.StringReader;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * 执行 API 返回结果
 *
 * <pre>
 *
 * Created by zhenqin.
 * User: zhenqin
 * Date: 2022/12/6
 * Time: 下午6:07
 * Vendor: yiidata.com
 *
 * </pre>
 *
 * @author zhenqin
 */
@Slf4j
@RestController
@RequestMapping("/jmreport")
public class ApiExecutionController {

    /**
     * 使用Jackson的{@code JSONPath}配置
     */
    protected static final Configuration JACKSON_JSON_PATH_CONFIGURATION = Configuration.builder()
            .jsonProvider(new JacksonJsonProvider()).mappingProvider(new JacksonMappingProvider()).build();

    @Autowired
    JimuReportDbService jimuReportDbService;

    /**
     * API 图表，打开看板时的实时数据调用
     * @param apiSelectVO
     * @return
     */
    @PostMapping(value = "/qurestApi0")
    public Result qurestApi(@RequestBody ApiSelectVO apiSelectVO) {
        final JimuReportDb reportDb = jimuReportDbService.getById(apiSelectVO.getApiSelectId());
        String url = reportDb.getApiUrl();
        try {
            Map<String, String> headers = new HashMap<>();
            if(StringUtils.isNotBlank(reportDb.getDbSource())) {
                StringReader reader = new StringReader(StringUtils.trimToNull(reportDb.getDbSource()));
                CharStreams.readLines(reader).stream().forEach(line -> {
                    final String[] splits = line.split(":");
                    if(splits.length >= 2 && StringUtils.isNotBlank(splits[0])) {
                        headers.put(StringUtils.trimToEmpty(splits[0]), StringUtils.trimToEmpty(splits[1]));
                    } else {
                        headers.put(StringUtils.trimToEmpty(splits[0]), "");
                    }
                });
            }

            // 支持多种协议
            final Map<String, Object> result = "POST".equalsIgnoreCase(reportDb.getApiMethod()) ?
                    RestApiUtils.post(url, null, headers, true) : RestApiUtils.get(url, null, headers, true);
            if(StringUtils.isNotBlank(reportDb.getApiConvert())) {

            }
            return ResultGenerator.genOkResult(result);
        } catch (Exception e) {
            log.error("访问 URL 异常。", e);
            return ResultGenerator.genFailedResult(500, e.getMessage());
        }
    }

    /**
     *
     * 保存 API 存储
     *
     * @return
     */
    @PostMapping(value = "/saveDb0")
    public Result saveDb0(@RequestBody JimuReportDb reportDb) {
        final JimuReportDb jimuReportDb = jimuReportDbService.getById(reportDb.getId());
        if(jimuReportDb == null) {
            reportDb.setCreateTime(new Date(System.currentTimeMillis()));
            jimuReportDbService.insertJimuReportDb(reportDb);
        } else {
            reportDb.setUpdateTime(new Date(System.currentTimeMillis()));
            jimuReportDbService.updateById(reportDb);
        }
        return ResultGenerator.genOkResult(reportDb);
    }

    /**
     * 在添加 API 时，执行 API 调用的返回
     * @param apiSelectVO
     * @return
     */
    @PostMapping(value = "/executeSelectApi0")
    public Result executeSelectApi(ApiFormVO apiSelectVO) {
        String url = apiSelectVO.getApi();
        try {
            Map<String, String> headers = new HashMap<>();
            if(StringUtils.isNotBlank(apiSelectVO.getHeaders())) {
                StringReader reader = new StringReader(StringUtils.trimToNull(apiSelectVO.getHeaders()));
                CharStreams.readLines(reader).stream().forEach(line -> {
                    final String[] splits = line.split(":");
                    if(splits.length >= 2 && StringUtils.isNotBlank(splits[0])) {
                        headers.put(StringUtils.trimToEmpty(splits[0]), StringUtils.trimToEmpty(splits[1]));
                    } else {
                        headers.put(StringUtils.trimToEmpty(splits[0]), "");
                    }
                });
            }
            // 支持多种协议
            final Map<String, Object> result = "POST".equalsIgnoreCase(apiSelectVO.getMethod()) ?
                    RestApiUtils.post(url, null, headers, true) : RestApiUtils.get(url, null, headers, true);
            List data = new ArrayList();
            if(StringUtils.isBlank(apiSelectVO.getApiConvert())) {
                // 默认是 data
                apiSelectVO.setApiConvert("data");
            }
            ReadContext context = JsonPath.parse(result);
            //在这里，“$”中为需要获取到json的路径
            data = context.read(getJsonPathString(apiSelectVO.getApiConvert()), new TypeRef<List<Map>>() {});
            // 没有读取到数据
            if(data == null || data.isEmpty()) {
                throw new IllegalStateException("api: " + apiSelectVO.getApi() + " 没有读取到数据。");
            }
            List list = new ArrayList();
            int i = 1;
            Map<String, Object> dd = (Map)data.get(0);
            for (Map.Entry<String, Object> entry : dd.entrySet()) {
                Map<String, Object> d = new HashMap<>();
                d.put("isShow", true);
                d.put("orderNum", i);
                d.put("fieldName", entry.getKey());
                d.put("fieldText", entry.getKey());
                d.put("widgetType", entry.getValue().getClass().getSimpleName());
                i++;
                list.add(d);
            }
            //data.put("data", (List)map.get("data"));
            //System.out.println(apiSelectVO.getApiSelectId());
            return ResultGenerator.genOkResult(list);
        } catch (Exception e) {
            log.error("访问 URL 异常。", e);
            return ResultGenerator.genFailedResult(500, e.getMessage());
        }
    }


    private String getJsonPathString(String dataJsonPath) {
        String stdDataJsonPath = dataJsonPath.trim();
        if (StringUtils.isNotBlank(stdDataJsonPath)) {
            // 转换"stores[0].books"、"[1].stores"简化模式为规范的JSONPath
            if (!stdDataJsonPath.startsWith("$")) {
                if (stdDataJsonPath.startsWith("[")) {
                    stdDataJsonPath = "$" + stdDataJsonPath;
                } else {
                    stdDataJsonPath = "$." + stdDataJsonPath;
                }
            }
        }
        return stdDataJsonPath;
    }

}
